package com.example.jobtask.service;

import com.example.jobtask.entity.JobTask;
import com.example.jobtask.executor.TaskExecutor;
import com.example.jobtask.repository.JobTaskRepository;
import com.example.jobtask.scheduler.TaskScheduleManager;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 任务管理服务层
 */
@Service
@Transactional
public class JobTaskService {
    
    private static final Logger logger = LoggerFactory.getLogger(JobTaskService.class);
    
    @Autowired
    private JobTaskRepository jobTaskRepository;
    
    @Autowired
    private TaskScheduleManager taskScheduleManager;
    
    @Autowired
    private TaskExecutor taskExecutor;
    
    /**
     * 创建任务
     */
    public JobTask createTask(JobTask jobTask) {
        // 验证任务名称唯一性
        if (jobTaskRepository.findByTaskName(jobTask.getTaskName()).isPresent()) {
            throw new RuntimeException("任务名称已存在: " + jobTask.getTaskName());
        }
        
        // 验证Cron表达式
        if (!isValidCronExpression(jobTask.getCronExpression())) {
            throw new RuntimeException("无效的Cron表达式: " + jobTask.getCronExpression());
        }
        
        // 验证任务是否可执行
        if (!taskExecutor.validateTask(jobTask)) {
            throw new RuntimeException("任务验证失败，请检查类名和方法名是否正确");
        }
        
        // 保存任务
        JobTask savedTask = jobTaskRepository.save(jobTask);
        
        // 如果任务状态是ACTIVE，添加到调度器
        if (jobTask.getStatus() == JobTask.TaskStatus.ACTIVE) {
            taskScheduleManager.scheduleTask(savedTask);
        }
        
        logger.info("任务创建成功: {}", savedTask.getTaskName());
        return savedTask;
    }
    
    /**
     * 更新任务
     */
    public JobTask updateTask(Long id, JobTask jobTask) {
        JobTask existingTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        // 检查任务名称唯一性（排除当前任务）
        if (!existingTask.getTaskName().equals(jobTask.getTaskName()) &&
            jobTaskRepository.existsByTaskNameAndIdNot(jobTask.getTaskName(), id)) {
            throw new RuntimeException("任务名称已存在: " + jobTask.getTaskName());
        }
        
        // 验证Cron表达式
        if (!isValidCronExpression(jobTask.getCronExpression())) {
            throw new RuntimeException("无效的Cron表达式: " + jobTask.getCronExpression());
        }
        
        // 验证任务是否可执行
        if (!taskExecutor.validateTask(jobTask)) {
            throw new RuntimeException("任务验证失败，请检查类名和方法名是否正确");
        }
        
        // 如果任务在调度器中，先移除
        if (taskScheduleManager.isTaskScheduled(existingTask)) {
            taskScheduleManager.unscheduleTask(existingTask);
        }
        
        // 更新任务信息
        existingTask.setTaskName(jobTask.getTaskName());
        existingTask.setDescription(jobTask.getDescription());
        existingTask.setCronExpression(jobTask.getCronExpression());
        existingTask.setTargetClass(jobTask.getTargetClass());
        existingTask.setTargetMethod(jobTask.getTargetMethod());
        existingTask.setMethodParams(jobTask.getMethodParams());
        existingTask.setJavaFilePath(jobTask.getJavaFilePath());
        existingTask.setStatus(jobTask.getStatus());
        
        // 保存更新
        JobTask updatedTask = jobTaskRepository.save(existingTask);
        
        // 如果任务状态是ACTIVE，重新添加到调度器
        if (updatedTask.getStatus() == JobTask.TaskStatus.ACTIVE) {
            taskScheduleManager.scheduleTask(updatedTask);
        }
        
        logger.info("任务更新成功: {}", updatedTask.getTaskName());
        return updatedTask;
    }
    
    /**
     * 删除任务
     */
    public void deleteTask(Long id) {
        JobTask jobTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        // 如果任务在调度器中，先移除
        if (taskScheduleManager.isTaskScheduled(jobTask)) {
            taskScheduleManager.unscheduleTask(jobTask);
        }
        
        // 删除任务
        jobTaskRepository.delete(jobTask);
        
        logger.info("任务删除成功: {}", jobTask.getTaskName());
    }
    
    /**
     * 根据ID获取任务
     */
    @Transactional(readOnly = true)
    public Optional<JobTask> getTaskById(Long id) {
        return jobTaskRepository.findById(id);
    }
    
    /**
     * 根据任务名称获取任务
     */
    @Transactional(readOnly = true)
    public Optional<JobTask> getTaskByName(String taskName) {
        return jobTaskRepository.findByTaskName(taskName);
    }
    
    /**
     * 获取所有任务（分页）
     */
    @Transactional(readOnly = true)
    public Page<JobTask> getAllTasks(Pageable pageable) {
        return jobTaskRepository.findAll(pageable);
    }
    
    /**
     * 获取所有任务
     */
    @Transactional(readOnly = true)
    public List<JobTask> getAllTasks() {
        return jobTaskRepository.findAll();
    }
    
    /**
     * 根据状态获取任务
     */
    @Transactional(readOnly = true)
    public List<JobTask> getTasksByStatus(JobTask.TaskStatus status) {
        return jobTaskRepository.findByStatus(status);
    }
    
    /**
     * 获取所有活跃任务
     */
    @Transactional(readOnly = true)
    public List<JobTask> getActiveTasks() {
        return jobTaskRepository.findAllActiveTasks();
    }
    
    /**
     * 启动任务
     */
    public void startTask(Long id) {
        JobTask jobTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        if (jobTask.getStatus() == JobTask.TaskStatus.ACTIVE) {
            throw new RuntimeException("任务已经是活跃状态");
        }
        
        // 更新任务状态
        jobTask.setStatus(JobTask.TaskStatus.ACTIVE);
        jobTaskRepository.save(jobTask);
        
        // 添加到调度器
        taskScheduleManager.scheduleTask(jobTask);
        
        logger.info("任务启动成功: {}", jobTask.getTaskName());
    }
    
    /**
     * 暂停任务
     */
    public void pauseTask(Long id) {
        JobTask jobTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        if (jobTask.getStatus() == JobTask.TaskStatus.PAUSED) {
            throw new RuntimeException("任务已经是暂停状态");
        }
        
        // 更新任务状态
        jobTask.setStatus(JobTask.TaskStatus.PAUSED);
        jobTaskRepository.save(jobTask);
        
        // 暂停调度器中的任务
        if (taskScheduleManager.isTaskScheduled(jobTask)) {
            taskScheduleManager.pauseTask(jobTask);
        }
        
        logger.info("任务暂停成功: {}", jobTask.getTaskName());
    }
    
    /**
     * 恢复任务
     */
    public void resumeTask(Long id) {
        JobTask jobTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        if (jobTask.getStatus() != JobTask.TaskStatus.PAUSED) {
            throw new RuntimeException("只能恢复暂停状态的任务");
        }
        
        // 更新任务状态
        jobTask.setStatus(JobTask.TaskStatus.ACTIVE);
        jobTaskRepository.save(jobTask);
        
        // 恢复调度器中的任务
        if (taskScheduleManager.isTaskScheduled(jobTask)) {
            taskScheduleManager.resumeTask(jobTask);
        } else {
            taskScheduleManager.scheduleTask(jobTask);
        }
        
        logger.info("任务恢复成功: {}", jobTask.getTaskName());
    }
    
    /**
     * 停止任务
     */
    public void stopTask(Long id) {
        JobTask jobTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        // 更新任务状态
        jobTask.setStatus(JobTask.TaskStatus.STOPPED);
        jobTaskRepository.save(jobTask);
        
        // 从调度器中移除任务
        if (taskScheduleManager.isTaskScheduled(jobTask)) {
            taskScheduleManager.unscheduleTask(jobTask);
        }
        
        logger.info("任务停止成功: {}", jobTask.getTaskName());
    }
    
    /**
     * 立即执行任务
     */
    public void executeTaskNow(Long id) {
        JobTask jobTask = jobTaskRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("任务不存在: " + id));
        
        // 如果任务在调度器中，触发立即执行
        if (taskScheduleManager.isTaskScheduled(jobTask)) {
            taskScheduleManager.triggerTaskNow(jobTask);
        } else {
            // 如果不在调度器中，直接执行
            taskExecutor.executeTask(jobTask);
            
            // 更新执行信息
            jobTask.setLastExecutedAt(java.time.LocalDateTime.now());
            jobTask.setExecutionCount(jobTask.getExecutionCount() + 1);
            jobTaskRepository.save(jobTask);
        }
        
        logger.info("任务立即执行: {}", jobTask.getTaskName());
    }
    
    /**
     * 验证Cron表达式
     */
    private boolean isValidCronExpression(String cronExpression) {
        try {
            new CronExpression(cronExpression);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 初始化系统时加载所有活跃任务到调度器
     */
    public void initializeActiveTasks() {
        List<JobTask> activeTasks = getActiveTasks();
        for (JobTask task : activeTasks) {
            try {
                if (!taskScheduleManager.isTaskScheduled(task)) {
                    taskScheduleManager.scheduleTask(task);
                }
            } catch (Exception e) {
                logger.error("初始化任务失败: " + task.getTaskName(), e);
            }
        }
        logger.info("初始化完成，加载了 {} 个活跃任务", activeTasks.size());
    }
}